package com.black.play.component.base;

import com.black.play.common.unit.UnitProvider;
import lombok.Getter;
import lombok.Setter;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;

/**
 * @author ylx
 */
@Getter
@Setter
public class AppProgressBar extends JComponent
{
    public static final int HORIZONTAL = 0;

    public static final int VERTICAL = 1;

    public static final int PERCENT = 0;

    public static final int COUNT = 1;

    private int direction;

    private int model;

    private double total = 0;

    private double current = 0;

    private long start;

    private long leftTime;

    private double avgSpeed;

    private String speedUnit;

    private UnitProvider speedUnitProvider;

    // 背景颜色
    private Color backgroundColor = Color.cyan;

    // 文本颜色
    private Color foregroundColor = Color.BLACK;

    public AppProgressBar(Container parent)
    {
        this(parent, HORIZONTAL, PERCENT);
    }

    public AppProgressBar(Container parent, int direction, int model)
    {
        this(parent,
            direction,
            model,
            direction == HORIZONTAL ? parent.getWidth() : 20,
            direction == HORIZONTAL ? 20 : parent.getHeight());
    }

    public AppProgressBar(Container parent, int direction, int model, int width, int height)
    {
        this.direction = direction;
        this.model = model;
        setSize(width, height);
        parent.add(this);
    }

    public void initProgress(Number total)
    {
        SwingUtilities.invokeLater(() -> {
            this.total = total.doubleValue();
            repaint();
        });
    }

    public void setProgress(Number current)
    {
        SwingUtilities.invokeLater(() -> {
            long currentTime = System.currentTimeMillis();
            double newValue = current.doubleValue();
            if (this.current == 0)
            {
                start = currentTime;
                avgSpeed = 0;
            }
            else
            {
                avgSpeed = newValue / ((double)(currentTime - start) / 1000);
            }
            this.current = newValue;
            leftTime = (long)((total - newValue) / avgSpeed);
            repaint();
        });
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D)g.create();

        // 抗锯齿设置
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 绘制背景（圆角矩形）
        g2.setColor(backgroundColor);
        int radius = Math.min(getWidth(), getHeight()) >> 1;
        // 圆角半径
        double percent = total == 0 ? 0 : current / total;
        if (direction == HORIZONTAL)
        {
            g2.fill(new RoundRectangle2D.Float(0, 0, getWidth() * (float)percent, getHeight(), radius, radius));
        }
        else
        {
            g2.fill(new RoundRectangle2D.Float(0, 0, getWidth(), getHeight() * (float)percent, radius, radius));
        }
        // 设置文本颜色和绘制文本
        g2.setColor(foregroundColor);
        Font font = new Font("宋体", Font.PLAIN, 20);
        g2.setFont(font);
        FontMetrics fm = g2.getFontMetrics();
        String text;
        if (model == PERCENT)
        {
            text = String.format("%.2f%%", percent * 100);
        }
        else
        {
            text = String.format("%.2f/%.2f", current, total);
        }
        text += " | ";
        if (speedUnitProvider != null)
        {
            text += speedUnitProvider.get(avgSpeed);
        }
        else if (speedUnit != null)
        {
            text += avgSpeed + speedUnit;
        }
        else
        {
            text += avgSpeed;
        }
        text += " | " + leftTime + "s";
        int x = (getWidth() - fm.stringWidth(text)) / 2;
        int y = (getHeight() - fm.getHeight()) / 2 + fm.getAscent();
        g2.drawString(text, x, y);

        // 绘制边框
        g2.setStroke(new BasicStroke(2));
        g2.setColor(Color.GRAY); // 边框颜色
        g2.draw(new RoundRectangle2D.Float(0, 0, getWidth(), getHeight(), radius, radius));

        g2.dispose();
        super.paintComponent(g);
    }
}
